package com.sprouting.personal.controller;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sprouting.personal.annotations.ApiIdempotent;
import com.sprouting.personal.interfaces.common.Constant;
import com.sprouting.personal.interfaces.common.ConstantPath;
import com.sprouting.personal.model.common.ResultJson;
import com.sprouting.personal.model.common.jsr.AddGroup;
import com.sprouting.personal.model.common.jsr.UpdGroup;
import com.sprouting.personal.model.entity.Dict;
import com.sprouting.personal.model.entity.ShoppingCart;
import com.sprouting.personal.model.entity.UploadFile;
import com.sprouting.personal.model.vo.ShoppingCartVo;
import com.sprouting.personal.service.DictService;
import com.sprouting.personal.service.ShoppingCartService;
import com.sprouting.personal.service.UploadFileService;
import com.sprouting.personal.utils.CheckTool;
import com.sprouting.personal.utils.EntityTool;
import com.sprouting.personal.utils.IdTool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 购物
 *
 * @author ：LX（长沙麓谷）
 * @date 创建时间： 2022/9/16 8:36
 */
@RequestMapping("/shopping")
@RestController
@Slf4j
public class ShoppingCartController {


    @Autowired
    private ShoppingCartService shoppingCartService;
    @Autowired
    private DictService dictService;
    @Autowired
    private UploadFileService uploadFileService;

    /**
     * 文件存储基础路径
     */
    @Value("${upload.data.base.path}")
    private String basePath;
    /**
     * 上传图片类型
     */
    @Value("#{'${upload.image.type}'.split(',')}")
    private List<String> uploadImageTypeList;
    /**
     * 图片文件上传最大长度
     */
    @Value("${upload.image.max.length}")
    private Integer uploadImageMaxLength;


    /**
     * 分页查询物品信息
     * @param page 分页信息
     * @param shoppingCart 查询参数
     * @return
     */
    @PostMapping("/getShoppingCartListPage")
    public ResultJson getShoppingCartListPage(Page page, ShoppingCart shoppingCart){
        if (shoppingCart == null){
            shoppingCart = new ShoppingCart();
        }
        shoppingCart.setUserId(StpUtil.getLoginIdAsString());

        Page<ShoppingCartVo> shoppingCartListPage = shoppingCartService.getShoppingCartListPage(page, shoppingCart);
        // 添加图片信息
        List<ShoppingCartVo> records = shoppingCartListPage.getRecords();
        if (CollUtil.isEmpty(records)){
            return ResultJson.success(shoppingCartListPage);
        }
        List<String> idList = records.stream().map(ShoppingCartVo::getId).collect(Collectors.toList());
        List<UploadFile> uploadFileList = uploadFileService.getUploadFileByBindingIdList(idList);
        Map<String, List<UploadFile>> collect = uploadFileList.stream().collect(Collectors.groupingBy(UploadFile::getBindingId));
        for (ShoppingCartVo shoppingCartVo : records){
            String id = shoppingCartVo.getId();
            List<UploadFile> fileList = collect.get(id);
            shoppingCartVo.setUploadFileList(fileList);
        }

        return ResultJson.success(shoppingCartListPage);
    }


    /**
     * 删除购物信息
     * @param id 主键信息
     * @return
     */
    @PostMapping("/delShoppingCart")
    @ApiIdempotent
    public ResultJson delShoppingCart(String id){
        if (CheckTool.checkNull(id)){
            return ResultJson.errorIllegal();
        }

        // 查看旧的物品信息
        ShoppingCart shoppingCartDb = shoppingCartService.getShoppingCartById(id);
        if (shoppingCartDb == null){
            return ResultJson.errorPram();
        }
        List<UploadFile> uploadFileList = uploadFileService.getUploadFileByBindingId(id);

        shoppingCartService.delShoppingCart(shoppingCartDb, uploadFileList);

        // 删除完成，才继续清理图片
        if (CollUtil.isNotEmpty(uploadFileList)){
            for (UploadFile uploadFile : uploadFileList){
                String savePath = uploadFile.getSavePath();
                if (!CheckTool.checkNull(savePath)){
                    // 做容错措施，如果是目录，不进行操作，数据非常重要，一定要多检查
                    if (FileUtil.isFile(basePath + savePath)){
                        FileUtil.del(basePath + savePath);
                    } else {
                        log.error("要删除的是数据是目录，跳过该删除操作：{}", basePath + savePath);
                    }
                }
            }
        }

        return ResultJson.success(null);
    }

    /**
     * 保存购物信息
     * @param shoppingCart 购物信息
     * @param fileList 上传的图片
     * @return
     */
    @PostMapping("/saveShoppingCart")
    @ApiIdempotent
    public ResultJson saveShoppingCart(@Validated(AddGroup.class) ShoppingCart shoppingCart, @RequestParam(value = "file", required = false) MultipartFile[] fileList){
        if (CheckTool.checkNull(basePath)){
            return ResultJson.error("图片存储路径未初始化，请补充application.properties配置信息");
        }
        String msg = checkShoppingCart(shoppingCart);
        if (msg != null){
            return ResultJson.error(msg);
        }

        // 上传的物品信息
        List<UploadFile> uploadFileList = new ArrayList<>();
        // 上传的购物信息
        shoppingCart.setId(IdTool.getId());
        if (fileList != null && fileList.length > 0){
            String err = saveShoppingCartCover(fileList, uploadFileList, shoppingCart);
            if (err != null){
                return ResultJson.error(err);
            }
        }

        shoppingCart.setUserId(StpUtil.getLoginIdAsString());
        EntityTool.buildSaveBase(shoppingCart, StpUtil.getLoginIdAsString());
        shoppingCartService.saveShoppingCart(shoppingCart, uploadFileList);
        return ResultJson.success(shoppingCart);
    }

    /**
     * 更新购物信息
     * @param shoppingCart 购物车
     * @param fileList 上传的文件
     * @param pictureList 图片的id，将全部的图片ID给后端，后端根据该ID来确定哪些需要删除的
     * @return
     */
    @PostMapping("/updShoppingCart")
    @ApiIdempotent
    public ResultJson updShoppingCart(@Validated(UpdGroup.class) ShoppingCart shoppingCart, @RequestParam(value = "file", required = false) MultipartFile[] fileList, @RequestParam(value = "pictureList", required = false) List<String> pictureList){
        String msg = checkShoppingCart(shoppingCart);
        if (msg != null){
            return ResultJson.error(msg);
        }

        List<UploadFile> uploadFileDb = uploadFileService.getUploadFileByBindingId(shoppingCart.getId());
        // 上传的物品信息
        List<UploadFile> uploadFileList = new ArrayList<>();

        if (fileList != null && fileList.length > 0){
            String err = saveShoppingCartCover(fileList, uploadFileList, shoppingCart);
            if (err != null){
                return ResultJson.error(err);
            }
        }

        EntityTool.buildUpdBase(shoppingCart, StpUtil.getLoginIdAsString());
        shoppingCartService.updShoppingCart(shoppingCart, uploadFileList);

        // 删除图片,对于之前的旧图片进行处理
        if (CollUtil.isNotEmpty(pictureList)){
            if (CollUtil.isNotEmpty(uploadFileDb)){
                List<String> collect = uploadFileDb.stream().map(UploadFile::getId).collect(Collectors.toList());
                // 找到差集
                collect.removeAll(pictureList);
                if (CollUtil.isNotEmpty(collect)){
                    // 要删除的数据
                    for (String id : collect){
                        UploadFile delUpload = uploadFileService.getUploadFileById(id);
                        String savePath = delUpload.getSavePath();
                        if (FileUtil.isFile(basePath + savePath)){
                            FileUtil.del(basePath + savePath);
                        } else {
                            log.error("要删除的是数据是目录，跳过该删除操作：{}", basePath + savePath);
                        }

                        // 物理删除表,这里不做事务管理
                        uploadFileService.removeById(id);
                    }
                }
            }
        }
        return ResultJson.success(shoppingCart);
    }

    /**
     * 获取购物类型
     * @return
     */
    @PostMapping("/getShoppingCartType")
    public ResultJson getShoppingCartType(){
        List<Dict> dictList = dictService.getType(Constant.RetainDictGroup.SHOPPING_GROUP, StpUtil.getLoginIdAsString());
        return ResultJson.success(dictList);
    }

    /**
     * 保存购物图像信息
     * @param multipartFiles 上传的文件
     * @param uploadFileList 文件地址
     * @param shoppingCart 购物信息
     * @return
     */
    private String saveShoppingCartCover(MultipartFile[] multipartFiles, List<UploadFile> uploadFileList, ShoppingCart shoppingCart){
        // 先进行第一次的检查，防止中途出错导致脏数据
        for (MultipartFile multipartFile : multipartFiles){
            String originalFilename = multipartFile.getOriginalFilename();
            if (CheckTool.checkNull(originalFilename)){
                return "获取文件名失败";
            }
            String suffix = FileUtil.getSuffix(originalFilename).toLowerCase();
            if (CheckTool.checkNull(suffix)){
                // 检查特殊情况下的文件名不符合
                return "非法上传图片名，不支持的后缀";
            }
            if (uploadImageTypeList != null){
                if (!uploadImageTypeList.contains(suffix)){
                    return "上传图片类型不支持";
                }
            }
            if (multipartFile.getSize() > uploadImageMaxLength){
                return "上传图片超过限定大小";
            }
        }

        // 正式上传
        for (MultipartFile multipartFile : multipartFiles){
            String originalFilename = multipartFile.getOriginalFilename();
            String suffix = FileUtil.getSuffix(originalFilename).toLowerCase();
            String path = String.format(ConstantPath.Path.SHOPPING_ICO, basePath, StpUtil.getLoginIdAsString(), IdTool.getId(), suffix);
            File toFile = new File(path);
            // 上传路径
            if (!FileUtil.exist(toFile)){
                FileUtil.touch(toFile);
            }

            try {
                multipartFile.transferTo(toFile);
            } catch (IOException e) {
                log.error("图片上传失败", e);
                return "图片上传失败";
            }

            // 只保存相对路径
            String replacePath = path.replace(basePath, "");

            UploadFile uploadFile = new UploadFile();
            uploadFile.setId(IdTool.getId());
            uploadFile.setUserId(StpUtil.getLoginIdAsString());
            uploadFile.setBindingId(shoppingCart.getId());
            uploadFile.setFileType(Constant.FileType.IMG);
            uploadFile.setSavePath(replacePath);
            uploadFile.setType(Constant.FileSourceType.SHOPPING_CART);
            uploadFile.setDelResource(Constant.YesOrNo.NO);
            uploadFile.setTempFile(Constant.TempFile.PRODUCTION);
            EntityTool.buildSaveBase(uploadFile, StpUtil.getLoginIdAsString());
            uploadFileList.add(uploadFile);
        }

        return null;
    }

    /**
     * 校验收录的物品
     * @param shoppingCart 购物信息
     * @return
     */
    private String checkShoppingCart(ShoppingCart shoppingCart){
        ShoppingCart shoppingCartDb = shoppingCartService.getShoppingCartRepeatQuery(shoppingCart.getId(), StpUtil.getLoginIdAsString(), shoppingCart.getName());
        if (shoppingCartDb != null){
            return "该物品已入库，不需要重复录入";
        }

        return null;
    }
}
